
package mt.testcomm;

import static org.junit.Assert.*;

import java.io.IOException;
import java.net.UnknownHostException;
import java.util.Random;

import mt.Order;
import mt.comm.ClientSideMessage;
import mt.comm.CommunicationsClient;
import mt.comm.CommunicationsServer;
import mt.comm.ServerSideMessage.Type;

import org.junit.Test;

/**
 * @author Rui Rosa
 *
 * Test the communications server methods
 */

public class CommunicationsServerTest {

	private String name = "SOMETHING";
	private Order order = Order.createBuyOrder(name, "EDP", 20, 1);
	private Random random = new Random();
	
	/**
	 * Tests if the MicroTrader server starts.
	 */
	
	@Test
	public void testStart() {
		int port = random.nextInt(100);
		CommunicationsServer server = new CommunicationsServer(port);
		server.start();
		
		assertFalse(server.hasNextMessage());
		assertFalse(server.clientIsConnected(name));
	}

	/**
	 * Tests if the server gets the next message received from one of the clients
	 */
	
	@Test
	public void testGetNextMessage() {
		int port = random.nextInt(100);
		CommunicationsServer server = new CommunicationsServer(port);
		CommunicationsClient client = new CommunicationsClient(port);
		
		server.start();
		try {
			client.connect("localhost", name);
			
			Thread.sleep(500);
			assertTrue(server.hasNextMessage());
			assertEquals(server.getNextMessage().getType(), Type.CONNECTED);
			
		} catch (UnknownHostException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
	}
	
	/**
	 * Tests if the server can send an order to a client
	 */
	
	@Test
	public void testSendOrder() {
		int port = random.nextInt(100);
		CommunicationsServer server = new CommunicationsServer(port);
		CommunicationsClient client = new CommunicationsClient(port);
		
		server.start();
		try {
			client.connect("localhost", name);
			
			Thread.sleep(500);
			server.sendOrder(name, order);
			assertEquals(client.getNextMessage().getType(), ClientSideMessage.Type.ORDER);
			
		} catch (UnknownHostException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
	}

	/**
	 * Tests if the server is able to report an error to a client
	 */
	
	@Test
	public void testSendError() {
		int port = random.nextInt(100);
		CommunicationsServer server = new CommunicationsServer(port);
		CommunicationsClient client = new CommunicationsClient(port);
		
		server.start();
		try {
			client.connect("localhost", name);
			
			server.sendError(name, "Erro");
			assertEquals(client.getNextMessage().getType(), ClientSideMessage.Type.ERROR);
			
		} catch (UnknownHostException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	/**
	 * Tests through a nickname if a client is currently connected
	 */
	
	@Test
	public void testClientIsConnected() {
		int port = random.nextInt(100);
		CommunicationsServer server = new CommunicationsServer(port);
		CommunicationsClient client = new CommunicationsClient(port);
		
		server.start();
		try {
			client.connect("localhost", name);
			
			Thread.sleep(500);
			assertTrue(server.clientIsConnected(name));
			
		} catch (UnknownHostException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
	}

	/**
	 * Tests if the server is capable to disconnect a client
	 */
	
	@Test
	public void testDisconnectClient() {
		int port = random.nextInt(100);
		CommunicationsServer server = new CommunicationsServer(port);
		CommunicationsClient client = new CommunicationsClient(port);
		
		server.start();
		try {
			client.connect("localhost", name);
			
			Thread.sleep(500);
			assertTrue(server.clientIsConnected(name));
			
			server.disconnectClient(name);
			
			Thread.sleep(500);
			assertFalse(server.clientIsConnected(name));
			
			
		} catch (UnknownHostException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
	}

	/**
	 * Tests if the server disconnects and all the connections are shutdown
	 */
	
	@Test
	public void testDisconnectServer() {
		int port = random.nextInt(100);
		CommunicationsServer server = new CommunicationsServer(port);
		
		server.start();
		server.disconnectServer();
		
	}

}
